package com.leadingsoft.pwxk.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.leadingsoft.pwxk.enums.InterfaceEnum;

@Component
public class AesUtilTest {

	private static String uilHost;
	private static String token;

	private static String password;

	public static String getData(InterfaceEnum interfaceEnum, String dataid, String startTime) {

		String params = "token=" + token + "&dataid=" + dataid+"&pagesize=50000";
		// 参数拼接
		try {
			// 获取16进制密文
			if (null != startTime) {
				switch (interfaceEnum) {
				case EPS_Message:
					params += "&startdate=" + startTime;
					break;
				case EPS_REGISTER:
					params += "&begintime=" + startTime;
					break;
				case UNDO_INFO:
					params += "&begintime=" + startTime;
					break;
				default:
					break;
				}
			}
			String resturl = interfaceEnum.getName();
			String result = sendPost(uilHost + resturl, params);
			// System.out.println("解密前为：" + result);
			// 接口返回结果集用AES加密后，又把结果集转换为了16进制。所以解密时需要先把16进制转换为二进制。
			byte[] aesResult = decrypt(parseHexStr2Byte(result), password);
			// System.out.println("解密后为：" + new String(aesResult, "utf-8"));
			return new String(aesResult, "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}

	}

	/**
	 * post请求
	 * 
	 * @param url
	 *            接口地址
	 * @param param
	 *            参数
	 */
	public static String sendPost(String url, String param) {
		PrintWriter out = null;
		BufferedReader in = null;
		String result = "";
		try {
			URL realUrl = new URL(url);
			// 打开和URL之间的连接
			URLConnection conn = realUrl.openConnection();
			// 设置通用的请求属性
			conn.setRequestProperty("accept", "*/*");
			conn.setRequestProperty("connection", "Keep-Alive");
			conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
			// 发送POST请求必须设置如下两行
			conn.setDoOutput(true);
			conn.setDoInput(true);
			// 获取URLConnection对象对应的输出流
			out = new PrintWriter(conn.getOutputStream());
			// 发送请求参数
			out.print(param);
			// flush输出流的缓冲
			out.flush();
			// 定义BufferedReader输入流来读取URL的响应
			in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line;
			while ((line = in.readLine()) != null) {
				result += line;
			}
		} catch (Exception e) {
			System.out.println("发送 POST 请求出现异常！" + e);
			e.printStackTrace();
		}
		// 使用finally块来关闭输出流、输入流
		finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
		}
		return result;
	}

	/**
	 * 解密方法
	 * 
	 * @param content
	 *            AES加密过的内容（16进制）
	 * @param password
	 *            加密时的密码
	 * @return result 明文
	 */
	public static byte[] decrypt(byte[] content, String password) {
		try {
			KeyGenerator kgen = KeyGenerator.getInstance("AES");
			SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
			random.setSeed(password.getBytes());
			kgen.init(128, random);

			SecretKey secretKey = kgen.generateKey();
			byte[] enCodeFormat = secretKey.getEncoded();
			SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
			Cipher cipher = Cipher.getInstance("AES");
			cipher.init(Cipher.DECRYPT_MODE, key);
			byte[] result = cipher.doFinal(content);
			return result;
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 将16进制转换为二进制
	 * 
	 * @param hexStr
	 * @return
	 */
	public static byte[] parseHexStr2Byte(String hexStr) {
		if (hexStr.length() < 1)
			return null;
		byte[] result = new byte[hexStr.length() / 2];
		for (int i = 0; i < hexStr.length() / 2; i++) {
			int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
			int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
			result[i] = (byte) (high * 16 + low);
		}
		return result;
	}

	@SuppressWarnings("static-access")
	@Autowired
	public void setUilHost(@Value("${sync.url}") String uilHost) {
		this.uilHost = uilHost;
	}

	@SuppressWarnings("static-access")
	@Autowired
	public void setToken(@Value("${sync.token}") String token) {
		this.token = token;
	}

	@SuppressWarnings("static-access")
	@Autowired
	public void setPassword(@Value("${sync.password}") String password) {
		this.password = password;
	}
}
